/*
 * signature_check.cpp
 *
 *  Created on: 2014-2-10
 *      Author: fengsh
 */
#include "signature_check.h"
#include "com_lightsh_light_Light.h"

jstring getPackageName(JNIEnv* env, jobject context)
{
	jclass contextCls = env->FindClass("android/content/Context");
	jmethodID getMethod = env->GetMethodID(contextCls, "getPackageName", "()Ljava/lang/String;");
	if(getMethod != NULL)
	{
		jobject nameObj = env->CallObjectMethod(context, getMethod);
		if(nameObj == NULL)
		{
			return env->NewStringUTF("cant get packageName");;
		}
		else
		{
			return (jstring)nameObj;
		}
	}
	else
	{
		return env->NewStringUTF("cant get packageName method");
	}
}

int getSignatureHashCode(JNIEnv* env, jobject context)
{
	jobject sign = getSignatureObject(env, context);
	jclass cls = env->GetObjectClass(sign);
	jmethodID hashMid = env->GetMethodID(cls, "hashCode", "()I");
	int sig_value = (int)env->CallIntMethod(sign, hashMid);
	return sig_value;
}
jbyteArray getSignatureValue(JNIEnv* env, jobject context)
{
	jobject sign = getSignatureObject(env, context);
	jclass cls = env->GetObjectClass(sign);
	jmethodID toByteMid = env->GetMethodID(cls, "toByteArray", "()[B");
	jbyteArray signBytes = (jbyteArray)env->CallObjectMethod(sign, toByteMid);

	return signBytes;
}
jstring getSignatureStr(JNIEnv* env, jobject context){
	jbyteArray signBytes = getSignatureValue(env, context);

	int arraySize = env->GetArrayLength(signBytes);
	jbyte* signValue = env->GetByteArrayElements(signBytes, JNI_FALSE);
	char* printValue = byteToHexStr((char*)signValue, arraySize);
	jstring result = env->NewStringUTF(printValue);
	delete [] printValue;
	return result;
}

jobject getSignatureObject(JNIEnv* env, jobject context)
{
	jclass cls = env->FindClass("android/content/ContextWrapper");
	jmethodID getpmMid = env->GetMethodID(cls, "getPackageManager", "()Landroid/content/pm/PackageManager;");
	jobject pm = env->CallObjectMethod(context, getpmMid);
	jstring packageName = getPackageName(env, context);

	cls = env->GetObjectClass(pm);
	jmethodID getpiMid = env->GetMethodID(cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");

	//GET_SIGNATURES = 64;
	cls = env->FindClass("android/content/pm/PackageManager");
	jfieldID getSignatureFieldId = env->GetStaticFieldID(cls, "GET_SIGNATURES", "I");
	jobject packageInfo = env->CallObjectMethod(pm, getpiMid, packageName, env->GetStaticIntField(cls, getSignatureFieldId));

	cls = env->GetObjectClass(packageInfo);
	jfieldID fid = env->GetFieldID(cls, "signatures", "[Landroid/content/pm/Signature;");
	jobjectArray signatures = (jobjectArray)env->GetObjectField(packageInfo, fid);

	jobject sig = env->GetObjectArrayElement(signatures, 0);
	return sig;
}

char* byteToHexStr(char* bytes, int size)
{
	char hex_table[17] = "0123456789abcdef";
	char* hex_str = new char[2*size + 1];
	memset(hex_str, 0, 2*size + 1);
	for(int i = 0; i < size; i++)
	{
		char _by = bytes[i];
		hex_str[2*i] = hex_table[(_by >> 4)&0x0F];
		hex_str[2*i+1] = hex_table[_by & 0x0F];
	}
	return hex_str;
}
